﻿namespace ConsoleExample
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Reflection;
    using LinqToLdap;
    using LinqToLdap.Collections;

    using LinqToLdapExtensions;
    using LinqToLdapExtensions.Domain;
    using LinqToLdapExtensions.Json;

    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using Newtonsoft.Json.Serialization;

    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here.")]
    public class Program
    {
        public static void Main(string[] args)
        {
            // first create a factory with some configuration 
            // (there are the same overloads as DirectoryContext provides).
            var factory = new DirectoryContextFactory(
                scopeState: ScopeState.ThreadStatic, 
                configuration: DomainSetup.SetupConfiguration());

            // create a unit of work instance
            var unitOfWork = new DirectoryContextUnitOfWork(factory);

            // call begin to initialize a context and bind it to the current thread
            unitOfWork.BeginUnitOfWork();

            // do some work
            var result = unitOfWork.CurrentContext.Query<InetOrgPerson>(
                    System.DirectoryServices.Protocols.SearchScope.OneLevel)
                            .Take(100)
                            .ToList();

            foreach (var user in result)
            {
                Console.WriteLine(user.Uid);
            }
            
            var resultB = unitOfWork.CurrentContext.Query(DomainSetup.ServerRoot).Take(10).ToList();

            // testing...
            var json = JsonConvert.SerializeObject(resultB, Formatting.Indented, new DirectoryAttributesConverter());
            
            var obj = JsonConvert.DeserializeObject<List<IDirectoryAttributes>>(json, new DirectoryAttributesConverter());

            // end the unit of work which will unbind and dispose the context
            unitOfWork.EndUnitOfWork();
        }
    }
}
